package com.example.software.websocket;

import com.example.software.entity.Message;
import com.example.software.service.MessageService;
import com.example.software.vo.MessageVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/api/ws/messages/{userId}")
@Component
public class MessageWebSocketServer {
    
    private static final Logger log = LoggerFactory.getLogger(MessageWebSocketServer.class);
    
    /**
     * 用于存储所有在线用户的WebSocket连接，key是userId，value是WebSocket会话对象
     */
    private static final Map<Long, Session> ONLINE_USERS = new ConcurrentHashMap<>();
    
    /**
     * 由于WebSocket采用多例模式，使用静态变量保存Service
     */
    private static MessageService messageService;
    
    private static ObjectMapper objectMapper;
    
    @Autowired
    public void setMessageService(MessageService messageService) {
        MessageWebSocketServer.messageService = messageService;
    }
    
    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        MessageWebSocketServer.objectMapper = objectMapper;
    }
    
    /**
     * 建立连接时调用
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        log.info("WebSocket连接建立 - 用户ID: {}, 会话ID: {}", userId, session.getId());
        
        // 将用户加入在线用户列表
        ONLINE_USERS.put(userId, session);
        
        try {
            // 获取用户未读消息数量，并发送给客户端
            int unreadCount = messageService.getUnreadMessageCount(userId);
            sendUnreadCount(session, unreadCount);
            
            log.info("WebSocket发送未读消息数量 - 用户ID: {}, 数量: {}", userId, unreadCount);
        } catch (Exception e) {
            log.error("WebSocket连接建立时发生错误", e);
        }
    }
    
    /**
     * 关闭连接时调用
     */
    @OnClose
    public void onClose(@PathParam("userId") Long userId) {
        log.info("WebSocket连接关闭 - 用户ID: {}", userId);
        
        // 将用户从在线用户列表移除
        ONLINE_USERS.remove(userId);
    }
    
    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error, @PathParam("userId") Long userId) {
        log.error("WebSocket发生错误 - 用户ID: {}, 错误: {}", userId, error.getMessage());
        
        // 关闭连接
        try {
            session.close();
        } catch (IOException e) {
            log.error("关闭WebSocket连接时发生错误", e);
        }
    }
    
    /**
     * 收到消息时调用
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("userId") Long userId) {
        log.info("WebSocket收到消息 - 用户ID: {}, 消息: {}", userId, message);
        
        // 这里可以处理接收到的消息，如果需要的话
    }
    
    /**
     * 发送未读消息数量给客户端
     */
    private void sendUnreadCount(Session session, int count) throws IOException {
        // 构建JSON消息
        WebSocketMessage message = new WebSocketMessage();
        message.setType("unread_count");
        message.setCount(count);
        
        // 发送消息
        session.getBasicRemote().sendText(objectMapper.writeValueAsString(message));
    }
    
    /**
     * 通知用户有新消息
     */
    public static void notifyNewMessage(Message message) {
        try {
            // 获取接收者会话
            Session receiverSession = ONLINE_USERS.get(message.getReceiverId());
            if (receiverSession != null && receiverSession.isOpen()) {
                // 构建JSON消息
                WebSocketMessage wsMessage = new WebSocketMessage();
                wsMessage.setType("new_message");
                
                // 转换消息为VO
                MessageVO messageVO = new MessageVO();
                messageVO.setId(message.getId());
                messageVO.setSenderId(message.getSenderId());
                messageVO.setReceiverId(message.getReceiverId());
                messageVO.setTaskId(message.getTaskId());
                messageVO.setContent(message.getContent());
                messageVO.setIsRead(message.getIsRead());
                messageVO.setCreateTime(message.getCreateTime());
                
                // 这里需要补充发送者名称和任务标题
                // 实际项目中应该在Service层查询并设置这些信息
                
                wsMessage.setMessage(messageVO);
                
                // 发送消息
                receiverSession.getBasicRemote().sendText(objectMapper.writeValueAsString(wsMessage));
                
                log.info("WebSocket通知新消息 - 接收者ID: {}, 消息ID: {}", message.getReceiverId(), message.getId());
            }
        } catch (Exception e) {
            log.error("WebSocket通知新消息时发生错误", e);
        }
    }
    
    /**
     * WebSocket消息类
     */
    public static class WebSocketMessage {
        private String type; // 消息类型：unread_count, new_message
        private Integer count; // 未读消息数量
        private MessageVO message; // 新消息内容
        
        public String getType() {
            return type;
        }
        
        public void setType(String type) {
            this.type = type;
        }
        
        public Integer getCount() {
            return count;
        }
        
        public void setCount(Integer count) {
            this.count = count;
        }
        
        public MessageVO getMessage() {
            return message;
        }
        
        public void setMessage(MessageVO message) {
            this.message = message;
        }
    }
} 